Passed
Push — master ( be82c0...67261f )
by Miloš
03:01
created

BaseAuthService   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 206
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 22
eloc 163
dl 0
loc 206
rs 10
c 0
b 0
f 0

14 Functions

Rating   Name   Duplication   Size   Complexity  
A redirectAfterLogin 0 5 2
A signInAnonymously 0 11 1
A signOut 0 15 3
A signInViaEmail 0 11 1
A signInByProvider 0 21 3
A redirectAfterSignOut 0 4 2
A signInViaTwitter 0 11 1
A subscribeUserChanges 0 14 2
A updateUserData 0 5 1
A signInViaGoogle 0 11 1
A getUser 0 9 2
A signInViaGithub 0 11 1
A signInViaFacebook 0 11 1
A signInViaPhone 0 11 1
1
import { Injectable } from "@angular/core";
2
import { AngularFireAuth } from "@angular/fire/auth";
3
import { Router } from "@angular/router";
4
import { Platform } from "@ionic/angular";
5
import { auth as firebaseAuth, User as FirebaseUser } from "firebase";
6
import { auth } from "firebase/app";
7
import { Observable } from "rxjs";
8
import { UniFirebaseLoginConfig } from "../config/uni-firebase-login-config";
9
import { UniFirebaseLoginConfigProvider } from "../config/uni-firebase-login-config-provider";
10
import { UserModel } from "../model/user-model";
11
import { AuthProvider } from "../providers/auth-provider";
12
import { IAuthProvider } from "../providers/i-auth-provider";
13
import { AuthStorageProvider } from "../storage/auth-storage-provider.service";
14
import { IAuthService } from "./i-auth-service";
15
16
@Injectable({
17
    providedIn: "root",
18
})
19
export class BaseAuthService<User extends UserModel = UserModel>
20
    implements IAuthService {
21
    public get user(): User | null {
22
        return this._user;
23
    }
24
25
    public get userInitialized() {
26
        return this._userInitialized;
27
    }
28
29
    public get currentFirebaseUser(): FirebaseUser | null {
30
        return firebaseAuth().currentUser;
31
    }
32
    protected config: UniFirebaseLoginConfig;
33
    protected _user: User | null = null;
34
    protected _userInitialized: boolean = false;
35
36
    public constructor(
37
        protected router: Router,
38
        protected platform: Platform,
39
        protected authProvider: AuthProvider,
40
        protected authStorageProvider: AuthStorageProvider<User>,
41
        protected angularFireAuth: AngularFireAuth,
42
        configProvider: UniFirebaseLoginConfigProvider,
43
    ) {
44
        this.config = configProvider.config;
45
        this.subscribeUserChanges();
46
    }
47
48
    public async signInByProvider(
49
        provider: IAuthProvider,
50
        redirect: boolean = true,
51
        callbackBeforeRedirect: (
52
            credential: auth.UserCredential | null,
53
        ) => Promise<void> | void = () => undefined,
54
    ): Promise<void> {
55
        const credential = await provider.handleLogin();
56
        if (
57
            this.config.storage !== false &&
58
            credential &&
59
            credential.user !== null
60
        ) {
61
            await this.authStorageProvider
62
                .getProvider()
63
                .updateStoredDataByFirebaseUser(credential.user);
64
        }
65
        await callbackBeforeRedirect(credential);
66
        if (redirect) {
67
            await this.redirectAfterLogin();
68
        }
69
    }
70
71
    public async signInAnonymously(
72
        redirect: boolean = true,
73
        callbackBeforeRedirect: (
74
            credential: auth.UserCredential | null,
75
        ) => Promise<void> | void = () => undefined,
76
    ): Promise<void> {
77
        await this.signInByProvider(
78
            this.authProvider.authAnonymous,
79
            redirect,
80
            callbackBeforeRedirect,
81
        );
82
    }
83
84
    public async signInViaEmail(
85
        redirect: boolean = true,
86
        callbackBeforeRedirect: (
87
            credential: auth.UserCredential | null,
88
        ) => Promise<void> | void = () => undefined,
89
    ): Promise<void> {
90
        await this.signInByProvider(
91
            this.authProvider.authEmail,
92
            redirect,
93
            callbackBeforeRedirect,
94
        );
95
    }
96
97
    public async signInViaFacebook(
98
        redirect: boolean = true,
99
        callbackBeforeRedirect: (
100
            credential: auth.UserCredential | null,
101
        ) => Promise<void> | void = () => undefined,
102
    ): Promise<void> {
103
        await this.signInByProvider(
104
            this.authProvider.authFacebook,
105
            redirect,
106
            callbackBeforeRedirect,
107
        );
108
    }
109
110
    public async signInViaGithub(
111
        redirect: boolean = true,
112
        callbackBeforeRedirect: (
113
            credential: auth.UserCredential | null,
114
        ) => Promise<void> | void = () => undefined,
115
    ): Promise<void> {
116
        await this.signInByProvider(
117
            this.authProvider.authGithub,
118
            redirect,
119
            callbackBeforeRedirect,
120
        );
121
    }
122
123
    public async signInViaGoogle(
124
        redirect: boolean = true,
125
        callbackBeforeRedirect: (
126
            credential: auth.UserCredential | null,
127
        ) => Promise<void> | void = () => undefined,
128
    ): Promise<void> {
129
        await this.signInByProvider(
130
            this.authProvider.authGoogle,
131
            redirect,
132
            callbackBeforeRedirect,
133
        );
134
    }
135
136
    public async signInViaPhone(
137
        redirect: boolean = true,
138
        callbackBeforeRedirect: (
139
            credential: auth.UserCredential | null,
140
        ) => Promise<void> | void = () => undefined,
141
    ): Promise<void> {
142
        await this.signInByProvider(
143
            this.authProvider.authPhone,
144
            redirect,
145
            callbackBeforeRedirect,
146
        );
147
    }
148
149
    public async signInViaTwitter(
150
        redirect: boolean = true,
151
        callbackBeforeRedirect: (
152
            credential: auth.UserCredential | null,
153
        ) => Promise<void> | void = () => undefined,
154
    ): Promise<void> {
155
        await this.signInByProvider(
156
            this.authProvider.authTwitter,
157
            redirect,
158
            callbackBeforeRedirect,
159
        );
160
    }
161
162
    /**
163
     * Handle sign out request
164
     */
165
    public async signOut(): Promise<void> {
166
        const currentUser = auth().currentUser;
167
168
        if (currentUser) {
169
            const providers = this.authProvider.getProvidersByUser(currentUser);
170
171
            for (const provider of providers) {
172
                await provider.handleSignOut();
173
            }
174
        }
175
        await this.redirectAfterSignOut();
176
    }
177
178
    /**
179
     * Get user profile data
180
     */
181
    public getUser(fromCache: boolean = true): Observable<User | null> {
182
        if (fromCache) {
183
            return this.authStorageProvider.getUser();
184
        } else {
185
            return this.authStorageProvider.getUserNonCached();
186
        }
187
    }
188
189
    public async updateUserData(user: User) {
190
        await this.authStorageProvider
191
            .getProvider()
192
            .updateStoredDataByUser(user);
193
    }
194
195
    protected async redirectAfterSignOut() {
196
        if (this.config.signInPage) {
197
            await this.router.navigate([this.config.signInPage]);
198
        }
199
    }
200
201
    protected async redirectAfterLogin() {
202
        if (this.config.afterSignInPage) {
203
            console.log("Redirect ", this.config.afterSignInPage);
204
            await this.router.navigate([this.config.afterSignInPage]);
205
        }
206
    }
207
208
    private subscribeUserChanges(): void {
209
        this.angularFireAuth.user.subscribe((user: any) => {
210
            this._userInitialized = true;
211
            if (user) {
212
                this.authStorageProvider
213
                    .getProvider()
214
                    .fetchUserFromStorageByFirebaseUser(user)
215
                    .subscribe(result => {
216
                        this._user = result;
217
                    });
218
            } else {
219
                // Logged out
220
                this._user = null;
221
            }
222
        });
223
    }
224
}
225